package org.jcubic.mvc.servlet;


import org.jcubic.mvc.annotation.Controller;
import org.jcubic.mvc.annotation.Request;
import org.jcubic.mvc.annotation.RequestMethod;
import org.jcubic.mvc.mapping.RequestMapping;
import org.jcubic.mvc.mapping.RequestMappingManager;
import org.jcubic.v.core.Config.Config;
import org.jcubic.v.core.ConfigHelper;
import org.jcubic.v.core.utils.ClassUtils;

import javax.servlet.ServletContext;
import java.lang.reflect.Method;
import java.util.Set;

public class AppMVCContext {

    private Config config = ConfigHelper.getConfig();

    private ServletContext servletContext;

    private static RequestMappingManager requestMappingManager = new RequestMappingManager();
    private static AppMVCContext appMVCContext;

    public static AppMVCContext getInstance() {
        if (appMVCContext == null) {
            appMVCContext = new AppMVCContext();
        }
        if (requestMappingManager == null) {
            requestMappingManager = new RequestMappingManager();
        }
        return appMVCContext;
    }

    private AppMVCContext() {
    }

    /**
     * Web 容器启动时，初始化项目环境
     *
     * @param servletContext Servlet Application
     */
    public void onStartup(ServletContext servletContext) {
        this.servletContext = servletContext;
        servletContext.setAttribute("config", config);
        String controllerPackage = config.getWeb().getControllerPackage();
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        Set<String> className = ClassUtils.getClassName(controllerPackage, true);
        if (className != null) {

            for (String name : className) {
                try {
                    //读取Controller类
                    Class<?> aClass = loader.loadClass(name);
                    if (aClass.isAnnotationPresent(Controller.class)) {
                        Method[] methods = aClass.getMethods();
                        //解析 所有添加了 @Request 注解的方法
                        String rootClassName = aClass.getName();


                        String[] parentUrl = null;
                        RequestMethod[] parentMethod = null;
                        if (aClass.isAnnotationPresent(Request.class)) {
                            Request qequest = aClass.getAnnotation(Request.class);
                            parentUrl = qequest.value();
                            parentMethod = qequest.method();
                        }


                        for (Method me : methods) {
                            RequestMapping requestMapping = new RequestMapping();
                            if (me.isAnnotationPresent(Request.class)) {
                                Request qequest = me.getAnnotation(Request.class);

                                //设置Request 的请求URL 等参数
                                requestMapping.setUrl(qequest.value());

                                if (requestMapping.getMethod() == null && parentMethod != null) {
                                    requestMapping.setMethod(parentMethod);
                                } else {
                                    requestMapping.setMethod(qequest.method());
                                }
                                requestMapping.setMethod(requestMapping.getMethod());
                                requestMapping.setMethodName(me.getName());
                                requestMapping.setClassName(rootClassName);
                                rootClassName += rootClassName + "." + me.getName();
                                requestMapping.setClassFullName(rootClassName);


                                if (parentUrl != null && parentUrl.length >= 1) {
                                    for (String u : parentUrl) {
                                        u = fixUrlPrefix(u);
                                        for (String url : requestMapping.getUrl()) {
                                            url = fixUrlPrefix(url);
                                            String currentUrl = u + url;
                                            System.out.println("url [" + currentUrl + "]");
                                            requestMappingManager.getStringRequestMappingMap().put(currentUrl, requestMapping);//put 进 Mapping 管理
                                        }

                                    }
                                } else {
                                    for (String url : requestMapping.getUrl()) {
                                        url = fixUrlPrefix(url);
                                        String currentUrl = url;
                                        System.out.println("url [" + currentUrl + "]");
                                        requestMappingManager.getStringRequestMappingMap().put(currentUrl, requestMapping);//put 进 Mapping 管理
                                    }
                                }

                            }
                        }
                        requestMappingManager.setClassName(rootClassName);


                    }
                } catch (ClassNotFoundException e) {
                    System.out.println("类[" + name + "] 不存在");
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 处理URL的前部，判断是否需要在url前面添加 / 如 user -> /user
     *
     * @param url 需处理的URL
     * @return 处理后的URL  如 /user
     */
    private String fixUrlPrefix(String url) {
        if (!url.equals("") && !url.startsWith("/")) {
            url = "/" + url;
        }
        return url;
    }



    public Config getConfig() {
        return config;
    }

    public void setConfig(Config config) {
        this.config = config;
    }

    public static RequestMappingManager getRequestMappingManager() {
        return requestMappingManager;
    }

    public static void setRequestMappingManager(RequestMappingManager requestMappingManager) {
        AppMVCContext.requestMappingManager = requestMappingManager;
    }
}
